package com.sm.tool.utils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;

/**
 * 
 * 对象Map转换工具类
 *
 * @author liqitian
 * @createDate 2018-12-27
 */
public class BeanMapperUtil {
    
    private volatile static BeanMapperUtil singleton;
    private BeanMapperUtil() {}

    public static BeanMapperUtil getInstance() {
        if (singleton == null) {
            synchronized (BeanMapperUtil.class) {
                if (singleton == null) {
                    singleton = new BeanMapperUtil();
                }
            }
        }
        return singleton;
    }

	/**
	 * bean 转化为map
	 * 
	 * @param bean
	 * @return
	 */
	public static HashMap<String, Object> beanToMap(Object bean) {
		HashMap<String, Object> map = new HashMap<String, Object>(16);
		if (null == bean) {
			return map;
		}
		Class<?> clazz = bean.getClass();
		BeanInfo beanInfo = null;
		try {
			beanInfo = Introspector.getBeanInfo(clazz);
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
		PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor descriptor : descriptors) {
			String propertyName = descriptor.getName();
			if (!"class".equals(propertyName)) {
				Method method = descriptor.getReadMethod();
				Object result;
				try {
					result = method.invoke(bean);
					if (null != result) {
						map.put(propertyName, result);
					}
				} catch (Exception e) {
					continue;
				}
			}
		}
		return map;
	}

	/**
	 * map 转化为 bean
	 * 
	 * @param clazz
	 * @param map
	 * @return
	 */
	public static Object mapToBean(Class<?> clazz, @SuppressWarnings("rawtypes") HashMap map) {
		Object object = null;
		try {
			object = clazz.newInstance();
			BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
			PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor descriptor : descriptors) {
				String propertyName = descriptor.getName();
				if (map.containsKey(propertyName)) {
					try {
						Object value = map.get(propertyName);
						Object[] args = new Object[1];
						args[0] = value;
						descriptor.getWriteMethod().invoke(object, args);
					} catch (Exception e) {
						continue;
					}
				}
			}
		} catch (Exception e) {
		}
		return object;
	}
}
